package org.mozhu.mboot.admin.system.account.web.controller;

import com.google.common.collect.Lists;
import org.apache.commons.lang3.StringUtils;
import org.mozhu.mboot.admin.system.account.entity.Gender;
import org.mozhu.mboot.admin.system.account.entity.User;
import org.mozhu.mboot.admin.system.account.service.UserService;
import org.mozhu.mboot.core.data.SearchFilters;
import org.mozhu.mboot.core.data.Searchable;
import org.mozhu.mboot.core.data.filter.Operator;
import org.mozhu.mboot.core.data.filter.SearchFilter;
import org.mozhu.mboot.core.web.Select2Response;
import org.mozhu.mboot.core.web.bind.annotation.ControllerDefaults;
import org.mozhu.mboot.core.web.controller.BaseCRUDController;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;

@RequestMapping("/system/account/user")
@Controller
@ControllerDefaults(resourceIdentity = "system:user")
public class UserController extends BaseCRUDController<User, Long> {

    protected UserService getBaseService() {
        return (UserService) baseService;
    }

    @Override
    protected void setCommonData(Model model) {
        super.setCommonData(model);
        model.addAttribute("genders", Gender.values());
    }

    @Override
    protected void beforeCreate(HttpServletRequest request, Model model, User user, BindingResult result, String backURL, RedirectAttributes redirectAttributes) {
        getBaseService().encryptPassword(user);
    }

    @Override
    protected void beforeUpdate(HttpServletRequest request, Model model, User user, BindingResult result, String backURL, RedirectAttributes redirectAttributes) {
        if (StringUtils.isNotBlank(user.getPlainPassword())) {
            getBaseService().encryptPassword(user);
        }
    }

    @RequestMapping(value = "/validate")
    @ResponseBody
    public Object validate(@RequestParam(value = "field") String field, @RequestParam(value = "fieldValue") String fieldValue,
                           @RequestParam(value = "id", required = false) String id) {
        if ("email".equals(field)) {
            User user = getBaseService().findByEmail(fieldValue);
            return user == null || (user.getId().toString().equals(id));
        }
        if ("loginName".equals(field)) {
            User user = getBaseService().findByLoginName(fieldValue);
            return user == null || (user.getId().toString().equals(id));
        }
        return null;
    }

    @RequestMapping(value = "/ajax/select/search", method = {RequestMethod.GET, RequestMethod.POST})
    @ResponseBody
    public Object selectSearch(@RequestParam(value = "query", defaultValue = "") String query, @RequestParam(value = "page", defaultValue = "1") Integer pageNumber) {
        SearchFilter searchFilter = SearchFilters.createFilter(Lists.newArrayList("name", "enName"), Operator.LIKE, query);
        // pageNumber start from 1 in page of select
        PageRequest pageable = PageRequest.of(pageNumber - 1, Select2Response.DEFAULT_SELECT_PAGE_SIZE);
        Searchable searchable = Searchable.newSearchable(pageable).addSearchFilter(searchFilter)
                .addSearchFilter("deleted", Operator.EQ, Boolean.FALSE)
                .addSearchFilter("activated", Operator.EQ, Boolean.TRUE);
        Page<User> result = getBaseService().findAll(searchable);
        return new Select2Response<>(result);
    }
}
